from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group, Permission
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework_simplejwt.views import TokenObtainPairView

from utils.pagination import CustomPagination
from .models import Profile, GroupExtraInfo
from .serializers import (
    CustomTokenObtainPairSerializer,
    ProfileSerializer,
    GroupSerializer,
    PermissionSerializer
)


# 登录
class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainPairSerializer


class ProfileViewSet(ModelViewSet):
    queryset = Profile.objects.select_related("user").order_by('id').all()
    serializer_class = ProfileSerializer
    permission_classes = [IsAuthenticated]

    def create(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return Response(
                {"detail": "必须提供有效的用户"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        data = request.data
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)

        instance = Profile.objects.create(
            user=request.user,
            chinese_name=serializer.validated_data.get("chinese_name"),
        )

        serialized_instance = ProfileSerializer(instance)
        headers = self.get_success_headers(serialized_instance.data)
        return Response(
            serialized_instance.data, status=status.HTTP_201_CREATED, headers=headers
        )

    @action(detail=False, methods=["GET", "PATCH"])
    def me(self, request):
        try:
            profile = request.user.profile
        except Profile.DoesNotExist:
            return Response(
                {"detail": "Profile not found."},
                status=status.HTTP_404_NOT_FOUND,
            )
        if request.method == "GET":
            serializer = ProfileSerializer(profile)
            response = {
                "data": serializer.data,
                "code": 0,
                "message": "Get user profile successfully",
            }
            return Response(response)
        elif request.method == "PATCH":
            serializer = ProfileSerializer(profile, data=request.data)
            serializer.is_valid(raise_exception=True)
            serializer.save()
            return Response(serializer.data)


class GroupViewSet(viewsets.ModelViewSet):
    queryset = Group.objects.order_by('id').all()
    serializer_class = GroupSerializer
    permission_classes = [IsAdminUser]

    @action(detail=True, methods=["patch"])
    def add_permission(self, request, pk=None):
        """给组添加权限"""
        group = self.get_object()
        permission_id = request.data.get("permission_id")
        try:
            permission = Permission.objects.get(id=permission_id)
        except Permission.DoesNotExist:
            return Response(
                {"detail": "Permission not found"}, status=status.HTTP_404_NOT_FOUND
            )

        group.permissions.add(permission)
        return Response(
            {"detail": "Permission added successfully"}, status=status.HTTP_200_OK
        )

    @action(detail=True, methods=["patch"])
    def remove_permissions(self, request, pk=None):
        """移除组的权限"""
        group = self.get_object()
        permission_id = request.data.get("permission_id")
        try:
            permission = Permission.objects.get(id=permission_id)
        except Permission.DoesNotExist:
            return Response(
                {"detail": "Permission not found"}, status=status.HTTP_404_NOT_FOUND
            )

        group.permissions.remove(permission)
        return Response(
            {"detail": "Permission removed successfully"}, status=status.HTTP_200_OK
        )

    @action(detail=True, methods=["post"])
    def add_user(self, request, pk=None):
        group = self.get_object()
        user_id = request.data.get("user_id")
        try:
            User = get_user_model()
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            return Response(
                {"detail": "User not found"}, status=status.HTTP_404_NOT_FOUND
            )

        # 检查用户是否已在该组中
        if group.user_set.filter(id=user.id).exists():
            return Response(
                {
                    "detail": f"User {user.username} is already a member of group {group.name}."
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        group.user_set.add(user)
        return Response(
            {"detail": f"User {user.username} added to group {group.name}"},
            status=status.HTTP_200_OK,
        )

    @action(detail=True, methods=["delete"])
    def remove_user(self, request, pk=None):
        """从组中移除用户"""
        group = self.get_object()
        user_id = request.data.get("user_id")
        try:
            User = get_user_model()
            user = User.objects.get(id=user_id)
        except User.DoesNotExist:
            return Response(
                {"detail": "User not found"}, status=status.HTTP_404_NOT_FOUND
            )

        # 检查用户是否在该组中
        if not group.user_set.filter(id=user.id).exists():
            return Response(
                {
                    "detail": f"User {user.username} is not a member of group {group.name}."
                },
                status=status.HTTP_400_BAD_REQUEST,
            )

        group.user_set.remove(user)  # 移除用户
        return Response(
            {"detail": f"User {user.username} removed from group {group.name}"},
            status=status.HTTP_200_OK,
        )

    def list(self, request, *args, **kwargs):
        """重写 list 方法，返回包装后的响应"""
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response({"code": 0, "data": serializer.data, "message": ""})

    def retrieve(self, request, *args, **kwargs):
        """重写 retrieve 方法，返回包装后的响应"""
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({"code": 0, "data": serializer.data, "message": ""})

    @action(detail=True, methods=["patch"])
    def code_name(self, request, pk=None):
        group = self.get_object()
        code_name = request.data.get("code_name")
        if not code_name:
            return Response({"detail": "code_name is required"}, status=status.HTTP_400_BAD_REQUEST)

        # 创建或更新 GroupExtraInfo 实例
        extra_info, created = GroupExtraInfo.objects.get_or_create(group=group)
        extra_info.code_name = code_name
        extra_info.save()

        return Response({"detail": "Code name updated successfully"}, status=status.HTTP_200_OK)

    @action(detail=True, methods=["get"])
    def permissions(self, request, pk=None):
        """获取角色的所有权限并分页"""
        group = self.get_object()  # 获取该角色
        permissions = group.permissions.order_by('id').all()  # 获取该角色所有的权限

        # 分页处理
        paginator = CustomPagination()
        result_page = paginator.paginate_queryset(permissions, request)
        serializer = PermissionSerializer(result_page, many=True)

        return paginator.get_paginated_response(serializer.data)


class UserPermissionViewSet(viewsets.ModelViewSet):
    User = get_user_model()
    queryset = User.objects.all()
    permission_classes = [IsAdminUser]
    lookup_field = "id"

    @action(detail=True, methods=["post"])
    def add_permission(self, request, id=None):
        user = self.get_object()
        permission_codename = request.data.get("codename")
        try:
            permission = Permission.objects.get(codename=permission_codename)
            user.user_permissions.add(permission)
            return Response(
                {
                    "detail": f"Permission '{permission_codename}' added to user '{user.username}'"
                },
                status=status.HTTP_200_OK,
            )
        except Permission.DoesNotExist:
            return Response(
                {"detail": "Permission not found"}, status=status.HTTP_404_NOT_FOUND
            )

    @action(detail=True, methods=["post"])
    def remove_permission(self, request, id=None):
        user = self.get_object()
        permission_codename = request.data.get("permission_codename")
        try:
            permission = Permission.objects.get(codename=permission_codename)
            user.user_permissions.remove(permission)
            return Response(
                {
                    "detail": f"Permission '{permission_codename}' removed from user '{user.username}'"
                },
                status=status.HTTP_200_OK,
            )
        except Permission.DoesNotExist:
            return Response(
                {"detail": "Permission not found"}, status=status.HTTP_404_NOT_FOUND
            )
